package fr.ece.ing4.si.gui;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.*;

import fr.ece.ing4.si.montecarloapplication.SetOfArguments;
import fr.ece.ing4.si.multithreadedmontecarlo.MultiThreadedMonteCarloSimulation;
import fr.ece.ing4.si.singlethreadedmontecarlo.MonteCarloSimulation;

public class CalculationPanel extends JPanel {

	private JLabel CallPutFlagLabel = new JLabel("CallPutFlag: ");
	private JLabel SLabel = new JLabel("S: ");
	private JLabel XLabel = new JLabel("X: ");
	private JLabel rLabel = new JLabel("r: ");
	private JLabel TLabel = new JLabel("T: ");
	private JLabel bLabel = new JLabel("b: ");
	private JLabel vLabel = new JLabel("v: ");
	private JLabel nStepsLabel = new JLabel("nSteps: ");
	private JLabel nSimulationsLabel = new JLabel("nSimulations: ");
	private JButton loadSet = new JButton("Load Set");
	private JButton loadCalculationSingle = new JButton("Calculation Single Thread");
	private JButton loadCalculationMulti = new JButton("Calculation Multi Thread");
	private JLabel singleThread = new JLabel("Single Thread");
	private JLabel multiThread = new JLabel("Multi Thread");
	private JLabel result1 = new JLabel();
	private JLabel result2 = new JLabel();
	private JLabel result3 = new JLabel();
	private JLabel result4 = new JLabel();
	private ArrayList<String> setList = new ArrayList<>();
	private JComboBox setChoice;

	public CalculationPanel(final ArrayList<SetOfArguments> tableOfArguments) {
		
		super();
		
		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		
		add(CallPutFlagLabel);
		add(SLabel);
		add(XLabel);
		add(rLabel);
		add(TLabel);
		add(bLabel);
		add(vLabel);
		add(nStepsLabel);
		add(nSimulationsLabel);
		
		
		for(int i=0 ; i<tableOfArguments.size() ; i++) {
			setList.add("Set " + Integer.toString(i));
		}
		
		setChoice = new JComboBox();
		
		for(int i=0 ; i<setList.size() ; i++) {
			setChoice.addItem(setList.get(i));
		}
		
		//Dimension d = new Dimension(10, 50);
		
		//setChoice.setPreferredSize(d);
		
		setChoice.setMaximumSize(getPreferredSize());
		
		add(setChoice);
		

		
		add(loadSet);
		
		add(loadCalculationSingle);
		
		loadSet.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				
				final int choice = setChoice.getSelectedIndex();
				CallPutFlagLabel.setText("CallPutFlag: " + tableOfArguments.get(choice).getCallPutFlag());
				SLabel.setText("S: " + tableOfArguments.get(choice).getS());
				XLabel.setText("X: " + tableOfArguments.get(choice).getX());
				rLabel.setText("r: " + tableOfArguments.get(choice).getr());
				TLabel.setText("T: " + tableOfArguments.get(choice).getT());
				bLabel.setText("b: " + tableOfArguments.get(choice).getb());
				vLabel.setText("v: " + tableOfArguments.get(choice).getv());
				nStepsLabel.setText("nSteps: " + tableOfArguments.get(choice).getnSteps());
				nSimulationsLabel.setText("nSimulations: " + tableOfArguments.get(choice).getnSimulations());
			}
		});
		
		add(singleThread);
		add(result1);
		add(result2);

		
		
		loadCalculationSingle.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				
				final int choice = setChoice.getSelectedIndex();
				double optionPrice = 0;
				long timeStart = 0, timeStop = 0, timeResult = 0;
				
				MonteCarloSimulation monteCarlo = new MonteCarloSimulation();
				
				timeStart = System.currentTimeMillis();
				
				optionPrice = monteCarlo.monteCarloStandardOption(	tableOfArguments.get(choice).getCallPutFlag(),
																	tableOfArguments.get(choice).getS(),
																	tableOfArguments.get(choice).getX(),
																	tableOfArguments.get(choice).getr(),
																	tableOfArguments.get(choice).getT(),
																	tableOfArguments.get(choice).getb(),
																	tableOfArguments.get(choice).getv(),
																	tableOfArguments.get(choice).getnSteps(),
																	tableOfArguments.get(choice).getnSimulations());
				
				timeStop = System.currentTimeMillis();
				
				timeResult = timeStop - timeStart;
				
				result1.setText("Option price: " + optionPrice);
				result2.setText("Calculation time: " + timeResult + " milliseconds");
			}
			});
		add(loadCalculationMulti);
				
		add(multiThread);
		add(result3);
		add(result4);
				
			loadCalculationMulti.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent arg0) {
					final int choice = setChoice.getSelectedIndex();
					double optionPrice2 = 0;
					long timeStart2 = 0, timeStop2 = 0, timeResult2 = 0;
					
					MultiThreadedMonteCarloSimulation multiMonteCarlo = new MultiThreadedMonteCarloSimulation();
					
					timeStart2 = System.currentTimeMillis();
					
						try {
							optionPrice2 = multiMonteCarlo.computeResult(		tableOfArguments.get(choice).getCallPutFlag(),
																				tableOfArguments.get(choice).getS(),
																				tableOfArguments.get(choice).getX(),
																				tableOfArguments.get(choice).getr(),
																				tableOfArguments.get(choice).getT(),
																				tableOfArguments.get(choice).getb(),
																				tableOfArguments.get(choice).getv(),
																				tableOfArguments.get(choice).getnSteps(),
																				tableOfArguments.get(choice).getnSimulations());
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}

					
					timeStop2 = System.currentTimeMillis();
					
					timeResult2 = timeStop2 - timeStart2;
					
					result3.setText("Option price: " + optionPrice2);
					result4.setText("Calculation time: " + timeResult2 + " milliseconds");
				}
			});

	}
}
